package com.qfedu.java1234.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.qfedu.java1234.common.constant.Constant;
import com.qfedu.java1234.entity.bo.PageBean;
import com.qfedu.java1234.entity.bo.Role;
import com.qfedu.java1234.entity.bo.SysUser;
import com.qfedu.java1234.entity.bo.UserRole;
import com.qfedu.java1234.entity.vo.ResultVO;
import com.qfedu.java1234.service.RoleService;
import com.qfedu.java1234.service.UserRoleService;
import com.qfedu.java1234.service.UserService;
import com.qfedu.java1234.util.DateUtil;
import com.qfedu.java1234.util.StringUtil;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.util.*;

/**
 * 用户controller控制器
 *
 * @ClassName UserController
 * @Author ykx
 * @Date 2024/4/23 17:03
 * @Version 1.0
 */
@RestController
@RequestMapping("sys/user")
public class UserController {

    @Autowired
    private UserService userService;

    @Autowired
    private RoleService roleService;

    @Autowired
    private UserRoleService userRoleService;

    @Autowired
    private BCryptPasswordEncoder bCryptPasswordEncoder;

    @Value("${avatarImagesFilePath}")
    private String avatarImagesFilePath;

    @PostMapping("/save")
    @PreAuthorize("hasAuthority('system:user:edit')||hasAuthority('system:user:add')")
    public ResultVO save(@RequestBody SysUser sysUser) {
        if (sysUser.getId() == null || sysUser.getId() == -1) {
            sysUser.setCreateTime(new Date());
            sysUser.setPassword(bCryptPasswordEncoder.encode(sysUser.getPassword()));
            userService.save(sysUser);
        } else {
            sysUser.setUpdateTime(new Date());
            userService.updateById(sysUser);
        }
        return ResultVO.success(Boolean.TRUE);
    }

    /**
     * 修改密码
     *
     * @param sysUser
     * @return
     */
    @PostMapping("/updateUserPwd")
    @PreAuthorize("hasAuthority('system:user:edit')")
    public ResultVO updateUserPwd(@RequestBody SysUser sysUser) {
        SysUser currentUser = userService.getById(sysUser.getId());
        if (bCryptPasswordEncoder.matches(sysUser.getOldPassword(), currentUser.getPassword())) {
            currentUser.setPassword(bCryptPasswordEncoder.encode(sysUser.getNewPassword()));
            currentUser.setUpdateTime(new Date());
            userService.updateById(currentUser);
        } else {
            return ResultVO.failed("输入旧密码错误！");
        }
        return ResultVO.success();
    }

    /**
     * 上传用户头像图片
     *
     * @param file
     * @return
     * @throws Exception
     */
    @RequestMapping("/uploadImage")
    @PreAuthorize("hasAuthority('system:user:edit')")
    public Map<String, Object> uploadImage(MultipartFile file) throws Exception {
        Map<String, Object> resultMap = new HashMap<>();
        if (!file.isEmpty()) {
            // 获取文件名
            String originalFilename = file.getOriginalFilename();
            String suffixName = originalFilename.substring(originalFilename.lastIndexOf("."));
            String newFileName = DateUtil.getCurrentDateStr() + suffixName;
            FileUtils.copyInputStreamToFile(file.getInputStream(), new File(avatarImagesFilePath + newFileName));
            resultMap.put("code", 0);
            resultMap.put("msg", "上传成功");
            Map<String, Object> dataMap = new HashMap<>();
            dataMap.put("title", newFileName);
            dataMap.put("src", "image/userAvatar/" + newFileName);
            resultMap.put("data", dataMap);
        }
        return resultMap;
    }

    /**
     * 修改用户头像
     *
     * @param sysUser
     * @return
     */
    @RequestMapping("/updateAvatar")
    @PreAuthorize("hasAuthority('system:user:edit')")
    public ResultVO updateAvatar(@RequestBody SysUser sysUser) {
        SysUser currentUser = userService.getById(sysUser.getId());
        currentUser.setUpdateTime(new Date());
        currentUser.setAvatar(sysUser.getAvatar());
        userService.updateById(currentUser);
        return ResultVO.success();
    }

    /**
     * 根据条件分页查询用户信息
     *
     * @param pageBean
     * @return
     */
    @PostMapping("/list")
    @PreAuthorize("hasAuthority('system:user:query')")
    public ResultVO list(@RequestBody PageBean pageBean) {
        String query = pageBean.getQuery().trim();
        Page<SysUser> pageResult = userService.page(new Page<>(pageBean.getPageNum(), pageBean.getPageSize()), new QueryWrapper<SysUser>().like(StringUtil.isNotEmpty(query), "username", query));
        List<SysUser> userList = pageResult.getRecords();
        for (SysUser user : userList) {
            List<Role> roleList = roleService.list(new QueryWrapper<Role>().inSql("id", "select role_id from sys_user_role where user_id=" + user.getId()));
            user.setSysRoleList(roleList);
        }
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("userList", userList);
        resultMap.put("total", pageResult.getTotal());
        return ResultVO.success(resultMap);
    }

    /**
     * 根据id查询
     *
     * @param id
     * @return
     */
    @GetMapping("/{id}")
    @PreAuthorize("hasAuthority('system:user:query')")
    public ResultVO findById(@PathVariable(value = "id") Integer id) {
        SysUser sysUser = userService.getById(id);
        return ResultVO.success(sysUser);
    }

    /**
     * 验证用户名
     *
     * @param sysUser
     * @return
     */
    @PostMapping("/checkUserName")
    @PreAuthorize("hasAuthority('system:user:query')")
    public ResultVO checkUserName(@RequestBody SysUser sysUser) {
        if (userService.getByUsername(sysUser.getUsername()) == null) {
            return ResultVO.success();
        } else {
            return ResultVO.failed();
        }
    }


    /**
     * 删除
     *
     * @param ids
     * @return
     */
    @Transactional
    @PostMapping("/delete")
    @PreAuthorize("hasAuthority('system:user:delete')")
    public ResultVO delete(@RequestBody List<Long> ids) {
        userService.removeByIds(ids);
        userRoleService.remove(new QueryWrapper<UserRole>().in("user_id", ids));
        return ResultVO.success(Boolean.TRUE);
    }

    /**
     * 重置密码
     *
     * @param id
     * @return
     */
    @GetMapping("/resetPassword/{id}")
    @PreAuthorize("hasAuthority('system:user:edit')")
    public ResultVO resetPassword(@PathVariable(value = "id") Integer id) {
        SysUser sysUser = userService.getById(id);
        sysUser.setPassword(bCryptPasswordEncoder.encode(Constant.DEFAULT_PASSWORD));
        sysUser.setUpdateTime(new Date());
        userService.updateById(sysUser);
        return ResultVO.success(Boolean.TRUE);
    }

    /**
     * 更新status状态
     *
     * @param id
     * @param status
     * @return
     */
    @GetMapping("/updateStatus/{id}/status/{status}")
    @PreAuthorize("hasAuthority('system:user:edit')")
    public ResultVO updateStatus(@PathVariable(value = "id") Integer id, @PathVariable(value = "status") String status) {
        SysUser sysUser = userService.getById(id);
        sysUser.setStatus(status);
        userService.saveOrUpdate(sysUser);
        return ResultVO.success();
    }

    /**
     * 用户角色授权
     *
     * @param userId
     * @param roleIds
     * @return
     */
    @Transactional
    @PostMapping("/grantRole/{userId}")
    @PreAuthorize("hasAuthority('system:user:role')")
    public ResultVO grantRole(@PathVariable("userId") Long userId, @RequestBody List<Long> roleIds) {
        List<UserRole> userRoleList = new ArrayList<>();
        roleIds.forEach(r -> {
            UserRole sysUserRole = new UserRole();
            sysUserRole.setRoleId(r);
            sysUserRole.setUserId(userId);
            userRoleList.add(sysUserRole);
        });
        userRoleService.remove(new QueryWrapper<UserRole>().eq("user_id", userId));
        userRoleService.saveBatch(userRoleList);
        return ResultVO.success();
    }

}
